package com.xia.netty.thread.lockSupport;

import java.util.concurrent.locks.LockSupport;

/**
 * 1.park: 阻塞线程 并且该线程在下列情况发生之前都会被阻塞:
 * ① 调用unpark函数，释放该线程的许可。
 * ② 该线程被中断。
 * ③ 设置的时间到了。并且，当time为绝对时间时，isAbsolute为true，否则，isAbsolute为false。
 * 当time为0时，表示无限等待，直到unpark发生
 * 2.unpark: 释放线程的许可 激活调用park后阻塞的线程
 * 3.区别wait,notify 调用park和unpark先后顺序无区别,不会造成阻塞
 *
 */
public class ParkAndUnParkDemo extends Thread {

    private Object object;

    public ParkAndUnParkDemo(Object object) {
        this.object = object;
    }

    @Override
    public void run() {
        System.out.println("before unpark");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //获取blocker
        Thread thread = (Thread) object;
        System.out.println("获取内存偏移量信息:" + LockSupport.getBlocker(thread));
        //释放线程许可, 激活调用park后的线程
        LockSupport.unpark(thread);
        //确保park中第二次设置偏移量为空方法执行
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //再次获取了偏移量信息  验证是否为null
        System.out.println("获取内存偏移量信息:" + LockSupport.getBlocker(thread));
        System.out.println("after unpark");

    }

    public static class TestPark {
        public static void main(String[] args) {
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName());
            ParkAndUnParkDemo parkAndUnParkDemo = new ParkAndUnParkDemo(thread);
            parkAndUnParkDemo.start();
            System.out.println("before park");
            // 获取许可
            LockSupport.park("ParkAndUnparkDemo");
            System.out.println("after park");
        }
    }

}
